package com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neusoft.bizcore.cache.caching.CacheService;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.neuiotms.dcvm.dto.ConfigDTO;
import com.neusoft.neuiotms.dcvm.service.ConfigService;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.constants.CmdbSynConstants;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.dto.PortFlowSummaryDto;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.ItSynApiService;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.PortFlowService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PortFlowServiceImpl implements PortFlowService {
    @Autowired
    private ConfigService configService;
    @Autowired
    private ItSynApiService itSynService;

    final SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    final SimpleDateFormat sdft3d = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    @Autowired
    private CacheService cacheService;

    @Override
    public void doCollect() {
        final Date end = this.formatNowDate();
        final Date start = this.getDateBeforeOrAfter(end, Calendar.MINUTE, -5);
        final ConfigDTO details = this.configService.details("dc_ports_rel");
        final String dcPortsRelData = details.getData();
        final JSONArray relArray = JSON.parseArray(dcPortsRelData);
        //数据中心流量计算结果对象集合
        relArray.forEach(rel -> {
            final JSONObject relJo = (JSONObject) rel;
            final String posCode = relJo.getString("PosCode");
            final String[] portsArray = relJo.getString("portIds").split(",");
            final List<PortFlowSummaryDto> listAllPortFlow = new ArrayList<>();
            for (final String portTrafficId : portsArray) {
                try {
                    final JSONObject itPortFlowData =
                            this.itSynService.getItPortFlowData(portTrafficId, this.sdft.format(start),
                                    this.sdft.format(end));
                    if (itPortFlowData.getString("responseCode").equals("0")) {
                        final String portTrafficDataStr = itPortFlowData.getString("portTrafficData");
                        final PortFlowSummaryDto portFlowSummaryDto = JsonUtils.jsonToPojo(portTrafficDataStr,
                                PortFlowSummaryDto.class);
                        listAllPortFlow.add(portFlowSummaryDto);
                    } else {
                        PortFlowServiceImpl.log.error("调用流量接口异常：端口id{}，异常描述{}", portTrafficId,
                                itPortFlowData.getString("responseDesc"));
                    }
                } catch (final Exception e) {
                    PortFlowServiceImpl.log.error(e.getMessage());
                    e.printStackTrace();
                }
            }

            //数据中心流量计算结果对象
            final JSONObject dcNetFlow = new JSONObject();
            dcNetFlow.put("code", posCode);
            dcNetFlow.put("collectedTime", this.sdft3d.format(start));
            final String data =
                    "[{\"code\":\"inFlow\",\"name\":\"入流量\",\"value\":9000.00,\"unit\":\"Mbps\"},{\"code\":\"inFlowHigh\",\"name\":\"入流量峰值\",\"value\":10000,\"unit\":\"Mbps\"},{\"code\":\"inFlowLow\",\"name\":\"入流量谷值\",\"value\":3000,\"unit\":\"Mbps\"},{\"code\":\"inFlowAvg\",\"name\":\"入流量均值\",\"value\":50000,\"unit\":\"Mbps\"},{\"code\":\"inFlowHighUR\",\"name\":\"入峰值利用率\",\"value\":0.70,\"unit\":\"\"},{\"code\":\"inFlowAvgUR\",\"name\":\"入均值利用率\",\"value\":0.9,\"unit\":\"\"},{\"code\":\"outFlow\",\"name\":\"出流量\",\"value\":9000.00,\"unit\":\"Mbps\"},{\"code\":\"outFlowHigh\",\"name\":\"出流量峰值\",\"value\":10000,\"unit\":\"Mbps\"},{\"code\":\"outFlowLow\",\"name\":\"出流量谷值\",\"value\":3000,\"unit\":\"Mbps\"},{\"code\":\"outFlowAvg\",\"name\":\"出流量均值\",\"value\":50000,\"unit\":\"Mbps\"},{\"code\":\"outFlowHighUR\",\"name\":\"出峰值利用率\",\"value\":0.70,\"unit\":\"\"},{\"code\":\"outFlowAvgUR\",\"name\":\"出均值利用率\",\"value\":0.9,\"unit\":\"\"}]";
            final JSONArray tempDataJa = JSON.parseArray(data);
            double inFlow = 0.00;
            double inFlowHigh = 0.00;
            double inFlowLow = 0.00;
            double inFlowAvg = 0.00;
            double inFlowHighUR = 0.00;
            double inFlowAvgUR = 0.00;

            double outFlow = 0.00;
            double outFlowHigh = 0.00;
            double outFlowLow = 0.00;
            double outFlowAvg = 0.00;
            double outFlowHighUR = 0.00;
            double outFlowAvgUR = 0.00;

            for (final PortFlowSummaryDto pf : listAllPortFlow) {
                final List<String> inFlow2 = pf.getInFlow();
                final double inFlowHigh2 = pf.getInFlowHigh();
                final double inFlowLow2 = pf.getInFlowLow();
                final double inFlowAvg2 = pf.getInFlowAvg();
                final double inFlowHighUR2 = pf.getInFlowHighUR();
                final double inFlowAvgUR2 = pf.getInFlowAvgUR();

                inFlow +=
                        (inFlow2 == null) || inFlow2.isEmpty() ? 0.00 : Double.valueOf(inFlow2.get(inFlow2.size() - 1));
                inFlowHigh += inFlowHigh2;
                inFlowLow += inFlowLow2;
                inFlowAvg += inFlowAvg2;
                inFlowHighUR += inFlowHighUR2;
                inFlowAvgUR += inFlowAvgUR2;

                final List<String> outFlow2 = pf.getOutFlow();
                final double outFlowHigh2 = pf.getOutFlowHigh();
                final double outFlowLow2 = pf.getOutFlowLow();
                final double outFlowAvg2 = pf.getOutFlowAvg();
                final double outFlowHighUR2 = pf.getOutFlowHighUR();
                final double outFlowAvgUR2 = pf.getOutFlowAvgUR();

                outFlow += (outFlow2 == null) || outFlow2.isEmpty() ? 0.00
                        : Double.valueOf(outFlow2.get(outFlow2.size() - 1));
                outFlowHigh += outFlowHigh2;
                outFlowLow += outFlowLow2;
                outFlowAvg += outFlowAvg2;
                outFlowHighUR += outFlowHighUR2;
                outFlowAvgUR += outFlowAvgUR2;
            }
            // 赋值
            for (int i = 0; i < tempDataJa.size(); i++) {
                final JSONObject jo = tempDataJa.getJSONObject(i);
                if (jo.getString("code").equals("inFlow")) {
                    jo.put("value", inFlow);
                } else if (jo.getString("code").equals("inFlowHigh")) {
                    jo.put("value", inFlowHigh);
                } else if (jo.getString("code").equals("inFlowLow")) {
                    jo.put("value", inFlowLow);
                } else if (jo.getString("code").equals("inFlowAvg")) {
                    jo.put("value", inFlowAvg);
                } else if (jo.getString("code").equals("inFlowHighUR")) {
                    jo.put("value", inFlowHighUR);
                } else if (jo.getString("code").equals("inFlowAvgUR")) {
                    jo.put("value", inFlowAvgUR);
                } else if (jo.getString("code").equals("outFlow")) {
                    jo.put("value", outFlow);
                } else if (jo.getString("code").equals("outFlowHigh")) {
                    jo.put("value", outFlowHigh);
                } else if (jo.getString("code").equals("outFlowLow")) {
                    jo.put("value", outFlowLow);
                } else if (jo.getString("code").equals("outFlowAvg")) {
                    jo.put("value", outFlowAvg);
                } else if (jo.getString("code").equals("outFlowHighUR")) {
                    jo.put("value", outFlowHighUR);
                } else if (jo.getString("code").equals("outFlowAvgUR")) {
                    jo.put("value", outFlowAvgUR);
                }
            }
            //singal final
            dcNetFlow.put("data", tempDataJa.toJSONString());

            //add cache
            if (this.cacheService.isInCache(CmdbSynConstants.FLOW_CACHE_NAME, posCode)) {
                this.cacheService.remove(CmdbSynConstants.FLOW_CACHE_NAME, posCode);
            }
            this.cacheService.put(CmdbSynConstants.FLOW_CACHE_NAME, posCode, dcNetFlow);
        });

        // 获取端口设备
        // 根据设备查询设备下端口
        // 根据端口查询流量信息
        // 计算整体数据中心流量数据:出/入流量：峰，谷，平均，峰利用率，均利用率

    }

    private Date formatNowDate() {
        final Date endTime = new Date();
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        final String endSdf = sdf.format(endTime) + ":00";
        Date end = null;
        try {
            end = this.sdft.parse(endSdf);
        } catch (final Exception e1) {
            PortFlowServiceImpl.log.info("queryDate  日期转换异常！");
        }
        return end;
    }

    /**
     * 得到若干小时、天、月前后的时间
     *
     * @param d
     * @param type
     * @param num
     * @return
     */
    public Date getDateBeforeOrAfter(final Date d, final int type, final int num) {
        final Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(type, now.get(type) + num);
        return now.getTime();
    }

}
